package com.ruoyi.test.geetest;

import org.apache.commons.lang3.RandomUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 截取原图和缺口图工具类
 */
public class GeetsSolveTools {

    public static String BASE_PATH = "D:\\home\\";
    //识别图像的大小
    public static int SHOT_IMG_WIDTH = 390;
    public static int SHOT_IMG_HEIGHT = 180;
    //识别图像的左上角 x y 坐标
    public static int SHOT_IMG_X = 100*9 + 43;
    public static int SHOT_IMG_Y = 400 + 70;

    //文档截图后图片大小
    private static Point imageFullScreenSize = null;


    private static BufferedImage getImageEle(ChromeDriver driver, String xpath){
        try {
            byte[] fullPage = driver.getScreenshotAs(OutputType.BYTES);
            BufferedImage fullImg = ImageIO.read(new ByteArrayInputStream(fullPage));
            ImageIO.write(fullImg, "png",  new File(BASE_PATH + "full.png"));
            if (imageFullScreenSize == null){
                imageFullScreenSize = new Point(fullImg.getWidth(), fullImg.getHeight());
            }
            WebElement ele = driver.findElement(By.xpath(xpath));
            Point point = ele.getLocation();

            BufferedImage eleScreenShot = fullImg.getSubimage(SHOT_IMG_X,SHOT_IMG_Y, SHOT_IMG_WIDTH, SHOT_IMG_HEIGHT);
            return eleScreenShot;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 通过xpath 获取原图
     * @param driver
     * @param xpatch
     */
    public static void obtainOriginalImg(ChromeDriver driver, String xpatch) throws IOException {
        BufferedImage image = GeetsSolveTools.getImageEle(driver,xpatch);
        ImageIO.write(image, "png",  new File(BASE_PATH + "original.png"));
    }

    /**
     * 通过 xpath 获取 滑块图（缺口图）
     * @param driver
     * @param xpath
     * @throws IOException
     */
    public static void obtainSliderImg(ChromeDriver driver, String xpath) throws IOException {
        BufferedImage image = GeetsSolveTools.getImageEle(driver,xpath);
        ImageIO.write(image, "png",  new File(BASE_PATH + "slider.png"));
    }

    /**
     * 根据original.png和slider.png计算需要移动的距离
     * @return
     */
    public static int calcMoveDistance(int GEETEST_WIDTH_START_POSTION) {
        //小方块距离左边界距离
        int START_DISTANCE = 6;
        int min = GEETEST_WIDTH_START_POSTION + START_DISTANCE - 10;
        try {
            BufferedImage geetest1 = ImageIO.read(new File(BASE_PATH + "original.png"));
            BufferedImage geetest2 = ImageIO.read(new File(BASE_PATH + "slider.png"));
            //跳过方块
            for(int i = (GEETEST_WIDTH_START_POSTION * 2  - GEETEST_WIDTH_START_POSTION/2 ) ; i < geetest1.getWidth();i ++){
                for(int j = 0; j < geetest1.getHeight(); j++){
                    int[] fullRgb = new int[3];
                    // 下面三行代码将一个数字转换为RGB数字
                    fullRgb[0] = (geetest1.getRGB(i, j)  & 0xff0000) >> 16;
                    fullRgb[1] = (geetest1.getRGB(i, j)  & 0xff00) >> 8;
                    fullRgb[2] = (geetest1.getRGB(i, j)  & 0xff);

                    int[] bgRgb = new int[3];
                    bgRgb[0] = (geetest2.getRGB(i, j)  & 0xff0000) >> 16;
                    bgRgb[1] = (geetest2.getRGB(i, j)  & 0xff00) >> 8;
                    bgRgb[2] = (geetest2.getRGB(i, j)  & 0xff);
                    int dif = difference(fullRgb, bgRgb);
                    //if(dif > 50)System.out.println("==difference==i:"+i+",dif=="+dif);
                    if(dif > 255){ //255
                        int moveDistance = i  - GEETEST_WIDTH_START_POSTION - START_DISTANCE;//(int)(i - START_DISTANCE);// / ((imageFullScreenSize.x + 0.0f)/ htmlFullScreenSize.x));
                        if(moveDistance <= 0 ){
                            //缺口都在右边
                            moveDistance = min;
                        }
                        System.out.println("==difference==x:"+i+",moveDistance=="+moveDistance);
                        return moveDistance;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.err.println("计算移动距离失败,取最小移动距离=="+min);
        return min;
    }

    public static int calcMoveDistance2(int GEETEST_WIDTH_START_POSTION) {
        //小方块距离左边界距离
        int START_DISTANCE = 6;
        int min = GEETEST_WIDTH_START_POSTION/2 ;
        try {
            BufferedImage geetest1 = ImageIO.read(new File(BASE_PATH + "original.png"));
            BufferedImage geetest2 = ImageIO.read(new File(BASE_PATH + "slider.png"));
            //跳过方块
            for(int i = geetest1.getWidth() - START_DISTANCE ; i >=0 ;i --){
                for(int j = 0; j < geetest1.getHeight(); j++){
                    int[] fullRgb = new int[3];
                    // 下面三行代码将一个数字转换为RGB数字
                    fullRgb[0] = (geetest1.getRGB(i, j)  & 0xff0000) >> 16;
                    fullRgb[1] = (geetest1.getRGB(i, j)  & 0xff00) >> 8;
                    fullRgb[2] = (geetest1.getRGB(i, j)  & 0xff);

                    int[] bgRgb = new int[3];
                    bgRgb[0] = (geetest2.getRGB(i, j)  & 0xff0000) >> 16;
                    bgRgb[1] = (geetest2.getRGB(i, j)  & 0xff00) >> 8;
                    bgRgb[2] = (geetest2.getRGB(i, j)  & 0xff);
                    int dif = difference(fullRgb, bgRgb);
                    //if(dif > 50)System.out.println("==difference==i:"+i+",dif=="+dif);
                    if(dif > 250){ //255
                        int moveDistance = i  - GEETEST_WIDTH_START_POSTION - GEETEST_WIDTH_START_POSTION/2 - START_DISTANCE;//(int)(i - START_DISTANCE);// / ((imageFullScreenSize.x + 0.0f)/ htmlFullScreenSize.x));
                        if(moveDistance <= 0 ){
                            //缺口都在右边
                            moveDistance = min;
                        }
                        System.out.println("==difference==x:"+i+",y:"+j+",moveDistance=="+moveDistance);
                        return moveDistance;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.err.println("计算移动距离失败,取最小移动距离=="+min);
        return min;
    }
    public static  List<MoveEntity> getMoveEntity(int distance){
        List<MoveEntity> list = new ArrayList<>();
        int i = 0;
        do {
            MoveEntity moveEntity = new MoveEntity();
            int r = RandomUtils.nextInt(3, 5);
            moveEntity.setX(r);
            //moveEntity.setY(RandomUtils.nextInt(0, 1)==1?RandomUtils.nextInt(0, 2):0-RandomUtils.nextInt(0, 2));
            int s = 0;
            if(i/Double.valueOf(distance)>0.05){
                if(i/Double.valueOf(distance)<0.85){
                    s = RandomUtils.nextInt(2, 5);
                }else {
                    s = RandomUtils.nextInt(10, 15);
                }
            }else{
                s = RandomUtils.nextInt(1, 10);
            }
            moveEntity.setSleepTime(s);
            list.add(moveEntity);
            i = i + r;
        } while (i <= distance );
        boolean cc = i > distance;
        for (int j = 0; j < Math.abs(distance - i); ) {
            int r = 1;//RandomUtils.nextInt(1, 2);
            MoveEntity moveEntity = new MoveEntity();
            moveEntity.setX(cc?-r:r);
            moveEntity.setY(0);
            moveEntity.setSleepTime(RandomUtils.nextInt(100, 200));
            list.add(moveEntity);
            j = j+r;
        }
        return list;
    }

    public static void moveSmallImg(Actions tmp, List<MoveEntity> list, int autoStep){
        int stepSum = 0;
        for(MoveEntity moveEntity : list){
            stepSum = stepSum + moveEntity.getX();
            tmp.moveByOffset(moveEntity.getX() , moveEntity.getY()).perform();
        }
        tmp.moveByOffset(autoStep, 0).perform();
        stepSum = stepSum + autoStep;
        System.out.println("======stempSum:"+stepSum);
    }
    private  static int difference(int[] a, int[] b){
        return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]) + Math.abs(a[2] - b[2]);
    }
}
